﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web.Mvc;

using ProjectBase.Core;
using ProjectBase.Core.Service;
using ProjectBase.Core.Web;
using ProjectBase.Mvc;

using $prjsn$.Common;
using $prjsn$.Common.Models;

namespace $safeprojectname$
{
    /// <summary>
    ///     I. Provides access to the Controllers and Actions based on the Menu.config file settings and CurrentRole.
    ///     The Menu.config is therefore used twice! Firstly for roles granting, secondly (NavigationFilterAttribute)
    ///     To be reused for hidding inaccessible controllers and actions. Time and bugs saving solution.
    ///     II. On action executed also checks, if the Model.MasterModel.IsReadOnly - then every action which is in
    ///     the WriteAction list is removed (models from actions and buttons).
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = true)]
    public class ChangeRoleAttribute : ActionFilterAttribute, IPublishingReporter
    {
        #region OnAction
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            this.PublishInfo(() => "OnActionExecuting--started-ChangeRoleFilter");
            if (!Global.Settings.UseCurrentRole) // Is Current role allowed
            {
                return;
            }

            if (DoChangeCurrentRole)
            {
                ChangeCurrentRole(filterContext);
            }
            this.PublishInfo(() => "OnActionExecuting-finished-ChangeRoleFilter");
        }

        /// <summary>
        ///     If Model is set to ReadOnly removes all the Write actions
        /// </summary>
        /// <param name = "filterContext"></param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            this.PublishInfo(() => "OnActionExecuted--started-ChangeRoleFilter");
            if (!Global.Settings.UseCurrentRole) // Is Current role allowed
            {
                return;
            }
            if (DoSelectRole)
            {
                SelectRole(filterContext);
            }
            if (DoGetComboBoxWCRoles)
            {
                GetComboBoxWCRoles(filterContext);
            }
            this.PublishInfo(() => "OnActionExecuted-finished-ChangeRoleFilter");
        }
        #endregion OnAction

        #region ChangeRole
        /// <summary>
        ///     Fills the Model with SubmitButton for Role change
        /// </summary>
        /// <param name = "filterContext"></param>
        protected virtual void SelectRole(ActionExecutedContext filterContext)
        {
            var controller = filterContext.Controller as IWebController<IViewModel>;
            if (controller.Is())
            {
                var model = controller.Model;
                model.MasterModel.CurrentAction = Str.Business.Services.SelectRole;

                model.MasterModel.ButtonSubmit = new ButtonItem(Str.Business.Services.SelectRole)
                {
                    FormAction = Str.Business.Services.RoleSelected,
                    FormController = controller.ControllerName,
                };
            }
        }

        /// <summary>
        ///     Provides the combobox with available roles.
        ///     This AOP filter method changes the result of the
        ///     'Home' controller's action 'GetComboBoxWCRoles'
        /// </summary>
        /// <param name = "filterContext"></param>
        protected virtual void GetComboBoxWCRoles(ActionExecutedContext filterContext)
        {
            var model = Factory.CreateInstance<IComboBoxModel>();
            model.ShowEmpty = true;
            if (SecurityManager.User.CurrentRole.IsEmpty())
            {
                model.ShowEmpty = false;
            }
            model.ComboBoxName = Str.Business.Home.Names.UserRoleList;

            var grantedRoles = SecurityManager
                .GetRolesForUser()
                .Where(r => SecurityManager.ApplicationRoles.Any(role => role.Equals(r, StringComparison.Ordinal)));

            model.Items = new SelectList(grantedRoles.ToDictionary(r => r, r => r), "key", "value",
                SecurityManager.User.CurrentRole);

            model.CssClassName = filterContext.HttpContext.Request.Params[Str.WebControls.Ajax.ParamCssClassName];

            filterContext.Controller.ViewData.Model = model;
            filterContext.Result = new ViewResult
            {
                ViewName = Str.WebControls.ComboBox,
                ViewData = filterContext.Controller.ViewData,
            };
        }

        protected virtual void ChangeCurrentRole(ControllerContext filterContext)
        {
            if (filterContext.HttpContext.Request.Form.AllKeys.Contains(Str.Business.Home.Names.UserRoleList))
            {
                var roleName = filterContext.HttpContext.Request.Form[Str.Business.Home.Names.UserRoleList];
                if (roleName.IsNotEmpty())
                {
                    SecurityManager.ChangeCurrentRole(roleName);
                }
            }
        }
        #endregion ChangeRole

        #region properties
        public virtual bool DoSelectRole { get; set; }
        public virtual bool DoGetComboBoxWCRoles { get; set; }
        public virtual bool DoChangeCurrentRole { get; set; }
        #endregion properties
    }
}